package com.gxgeek.calculator.script;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import lombok.extern.slf4j.Slf4j;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;

/**
 * @author gaoxing
 * @create 2018-06-04 下午8:06
 */
@Slf4j
public abstract class AbstractUnit implements Unit {
    public abstract Object _execute();
    private ThreadLocal<Object> data = new ThreadLocal<>();
    private ThreadLocal<List<Object>> args = new ThreadLocal<>();

    @Override
    public Object _run(Object unitDo, List<Object> param) {
        this.data.set(unitDo);
        this.args.set(param);
        log.debug("--debug--模型对象=[{}]", JSON.toJSONString(unitDo, SerializerFeature.WriteClassName));
        log.debug("--debug--参数列表=[{}]", JSON.toJSONString(args, SerializerFeature.WriteClassName));
        Object result;
        try {
            result = this._execute();
        } catch (Exception e) {
            log.error("模型对象=[{}]", JSON.toJSONString(unitDo, SerializerFeature.WriteClassName));
            log.error("参数列表=[{}]", JSON.toJSONString(args, SerializerFeature.WriteClassName));
            log.error("脚本名=[{}],计算失败",this.getClass().getSimpleName(),e);
            result = "ERROR";
        }
        log.debug("--debug--执行结果=[{}]", JSON.toJSONString(result, SerializerFeature.WriteClassName));
        this.args.remove();
        this.data.remove();


        return result;
    }

    public Object getData() {
        return this.data.get();
    }

    public Object args(int i) {
        List<Object> arg = this.args.get();
        if (i >= arg.size()) {
            return null;
        }
        return arg.get(i);
    }
    public Object getX() {
        return args(0);
    }

    public Object getY() {
        return args(1);
    }

    public Object getZ() {
        return args(2);
    }





//    utils
    /**
     * 获得当天最大时间
     * @param date
     * @return
     */
    protected Date getEndOfDay(Date date){
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault());;
        LocalDateTime endOfDay = localDateTime.with(LocalTime.MAX);
        return Date.from(endOfDay.atZone(ZoneId.systemDefault()).toInstant());
    }
    /**
     * 获得某天最小时间 2017-10-15 00:00:00
     * @param date
     * @return
     */
    protected  Date getStartOfDay(Date date) {
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault());
        LocalDateTime startOfDay = localDateTime.with(LocalTime.MIN);
        return Date.from(startOfDay.atZone(ZoneId.systemDefault()).toInstant());
    }

}
